package org.colin.aspect;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;

/**
 * @desc 打印接口的入参和出参AOP切面实现
 * @author wujiangbo
 * @date 2020年1月3日 下午5:14:33
 */
@Component
@Aspect
@Slf4j
public class RecordLogAspect {

	private final ObjectMapper mapper;

	@Autowired
	public RecordLogAspect(ObjectMapper mapper) {
		this.mapper = mapper;
	}

	@Pointcut(value = "execution(public * org.colin.controller.*.*(..))")
	public void recordLog() {
	}

	@Pointcut("@annotation(org.colin.annotation.Log)")
	private void cut() {
	}

	/**
	 * @desc 定制一个环绕通知
	 * @author wujiangbo
	 * @date 2020年1月3日 下午5:24:19
	 * @param joinPoint
	 * @return
	 */
	@Around("cut()")
	public Object advice(ProceedingJoinPoint joinPoint) {
		try {
			StringBuffer param = new StringBuffer();
			for (Object object : joinPoint.getArgs()) {
				if (object instanceof MultipartFile || object instanceof HttpServletRequest || object instanceof HttpServletResponse) {
					continue;
				}
				param.append(mapper.writeValueAsString(object)).append(",");
			}
			log.info(joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + ":[接口入参]: " + param.toString());
			final Object proceed = joinPoint.proceed();
			log.info(joinPoint.getTarget().getClass().getName() + "." + joinPoint.getSignature().getName() + ":[接口出参]: " + proceed);
			return proceed;
		} catch (Throwable e) {
			return new Exception("打印日志异常：" + e.getLocalizedMessage());
		}
	}

	@Before("cut()")
	public void before() {
	}

	@After(value = "recordLog()")
	public void after() {
	}
}
